// Tencent is pleased to support the open source community by making ncnn available.
//
// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
//
// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// https://opensource.org/licenses/BSD-3-Clause
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

package com.tencent.yolov8ncnn;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.PixelFormat;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.util.Size;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.Spinner;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.permissionx.guolindev.PermissionX;
import com.permissionx.guolindev.callback.RequestCallback;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;



public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {
    public static final int REQUEST_CAMERA = 100;
    public static final int REQUEST_RECORD = 101;

    private Yolov8Ncnn yolov8ncnn = new Yolov8Ncnn();
    private int facing = 0;

    private Spinner spinner_resolution;
    private Spinner spinnerCPUGPU;
    private int current_resolution = 0;
    private int current_cpugpu = 0;

    private SurfaceView cameraView;
    private boolean isRecordStarting = false;
    private String video_path;
    private CameraRecorder cameraRecorder;
    private String dir_path = "";
    private String[] resolutionArray = null;
    private void startRecord() {
        cameraRecorder = new CameraRecorder();
        cameraRecorder.setSavePath(video_path);
        try {
            Size previewSize = getPreviewSize();
            cameraRecorder.prepare(previewSize.getWidth(), previewSize.getHeight());
            cameraRecorder.start();
        } catch (IOException | InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        cameraView = (SurfaceView) findViewById(R.id.cameraview);

        cameraView.getHolder().setFormat(PixelFormat.RGBA_8888);
        cameraView.getHolder().addCallback(this);

        Button buttonRecord = (Button) findViewById(R.id.buttonRecord);
        resolutionArray = getResources().getStringArray(R.array.resolution_array);
        buttonRecord.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isRecordStarting) {
                    //结束录制
                    isRecordStarting = false;
                    buttonRecord.setText("开始巡检");
                    if (cameraRecorder != null) {
                        cameraRecorder.stop();
                        yolov8ncnn.stopRecord();
                        cameraRecorder = null;
                    }
                    // 发送广播，刷新多媒体库
                    Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
                    mediaScanIntent.setData(Uri.fromFile(new File(video_path)));
                    sendBroadcast(mediaScanIntent);
                    Log.e("xuyan==>media", "录制完成:" + video_path);
                } else {
                    //开始录制
                    isRecordStarting = true;
                    buttonRecord.setText("结束巡检");
                    dir_path = FileDir.getTimeDir();
                    File file = new File(dir_path, System.currentTimeMillis() + ".mp4");
                    file.getParentFile().mkdirs();
                    video_path = file.getPath();
                    yolov8ncnn.startRecord(dir_path, video_path);
                    startRecord();
                    Log.e("xuyan==>media", "开始录制");
                }
            }
        });
        Button buttonSwitchCamera = (Button) findViewById(R.id.buttonSwitchCamera);
        buttonSwitchCamera.setOnClickListener(arg0 -> {

            int new_facing = 1 - facing;
            Log.e("xuyan==>media", "closeCamera");
            yolov8ncnn.closeCamera();
            Size previewSize = getPreviewSize();
            yolov8ncnn.openCamera(new_facing,previewSize.getWidth(),previewSize.getHeight());


            facing = new_facing;
        });

        spinner_resolution = (Spinner) findViewById(R.id.spinner_resolution);
        spinner_resolution.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id) {
                if (position != current_resolution) {
                    current_resolution = position;
                    yolov8ncnn.closeCamera();
                    Size previewSize = getPreviewSize();
                    yolov8ncnn.openCamera(facing,previewSize.getWidth(),previewSize.getHeight());
                }
            }

            @Override
            public void onNothingSelected(AdapterView<?> arg0) {
            }
        });

//        spinnerCPUGPU = (Spinner) findViewById(R.id.spinnerCPUGPU);
//        spinnerCPUGPU.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
//            @Override
//            public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id) {
//                if (position != current_cpugpu) {
//                    current_cpugpu = position;
//                    reload();
//                }
//            }
//
//            @Override
//            public void onNothingSelected(AdapterView<?> arg0) {
//            }
//        });

        reload();



        List<String> requestList = new ArrayList<String>();
        requestList.add(Manifest.permission.CAMERA);
        requestList.add(Manifest.permission.RECORD_AUDIO);
        requestList.add(Manifest.permission.READ_EXTERNAL_STORAGE);
        requestList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            requestList.add(Manifest.permission.READ_MEDIA_IMAGES);
            requestList.add(Manifest.permission.READ_MEDIA_VIDEO);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
                requestList.add(Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED);
            }
        }

        PermissionX.init(this).permissions(requestList)
                .request((allGranted, grantedList, deniedList) -> {
                    if (allGranted) {
                        yolov8ncnn.setListener((data) -> {
                            if (cameraRecorder != null && isRecordStarting) {
                                cameraRecorder.feedData(data, 0L);
                            }
                        });
                        Log.e("MainActivity", "yolov8ncnn openCamera");
                        Size previewSize = getPreviewSize();
                        yolov8ncnn.openCamera(facing,previewSize.getWidth(),previewSize.getHeight());
                    }
                });
    }

    private void reload() {
        boolean ret_init = yolov8ncnn.loadModel(getAssets(), 0, 0);
        if (!ret_init) {
            Log.e("MainActivity", "yolov8ncnn loadModel failed");
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        yolov8ncnn.setOutputWindow(holder.getSurface());
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {


    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
    }


    @SuppressLint("CheckResult")
    @Override
    public void onResume() {
        super.onResume();

    }

    @Override
    public void onPause() {
        super.onPause();
//        Log.e("xuyan==>media", "onPause==>closeCamera");
//        yolov8ncnn.closeCamera()
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }
    private Size getPreviewSize() {
        String resolution = resolutionArray[current_resolution];
        Size size = new Size(480,640);
        if ("480P".equals(resolution)) {
            size = new Size(480,640);
        }else if ("720P".equals(resolution)){
            size = new Size(720,1280);
        }else if ("1080P".equals(resolution)){
            size = new Size(1080,1920);
        }
        return size;
    }
}
